module DynamicScaffoldResource # :nodoc:
  module ClassMethods
    def scaffold_resource(model_id, options = {})
      options.assert_valid_keys(:class_name)
      
      singular_name = model_id.to_s
      plural_name   = singular_name.pluralize
      class_name    = options[:class_name] || singular_name.camelize
      models_path   = plural_name + "_path"
      model_path    = singular_name + "_path"
      new_model_path = "new_#{singular_name}_path"
      edit_model_path = "edit_#{singular_name}_path"
      
      module_eval <<-"end_eval", __FILE__, __LINE__
        # GET /models
        # GET /models.xml
        def index
          @#{plural_name} = #{class_name}.find(:all)
          respond_to do |format|
            format.html {render_scaffold('index')}
            format.xml  { render :xml => @#{plural_name}.to_xml }
          end
        end
        
        # GET /models/1
        # GET /models/1.xml
        def show
          @#{singular_name} = #{class_name}.find(params[:id])
          
          respond_to do |format|
            format.html {render_scaffold}# show.rhtml
            format.xml  { render :xml => @#{singular_name}.to_xml }
          end
        end
        
        # GET /models/new
        def new
          @#{singular_name} = #{class_name}.new
          render_scaffold
        end

        # GET /models/1;edit
        def edit
          @#{singular_name} = #{class_name}.find(params[:id])
          render_scaffold
        end
   
        # POST /models
        # POST /model.xml
        def create
          @#{singular_name} = #{class_name}.new(params["#{singular_name}".to_sym])
          
          respond_to do |format|
            if @#{singular_name}.save
              flash[:notice] = '@#{singular_name} was successfully created.'
              
              format.html { redirect_to #{model_path}(@#{singular_name}) }
              format.xml do
                headers["Location"] = #{model_path}(@#{singular_name})
                render :nothing => true, :status => "201 Created"
              end
            else
              format.html { render_scaffold("new") }
              format.xml  { render :xml => @#{singular_name}.errors.to_xml }
            end
          end
        end

        # PUT /models/1
        # PUT /models/1.xml
        def update
          @#{singular_name} = #{class_name}.find(params[:id])
          
          respond_to do |format|
            if @#{singular_name}.update_attributes(params[:#{singular_name}])
              format.html { redirect_to #{model_path}(@#{singular_name}) }
              format.xml  { render :nothing => true }
            else
              format.html { render_scaffold("edit") }
              format.xml  { render :xml => @#{singular_name}.errors.to_xml }        
            end
          end
        end
        
        # DELETE /models/1
        # DELETE /models/1.xml
        def destroy
          @#{singular_name} = #{class_name}.find(params[:id])
          @#{singular_name}.destroy
          
          respond_to do |format|
            format.html { redirect_to #{models_path} }
            format.xml  { render :nothing => true }
          end
        end
        
        private
        
        def render_scaffold(action=nil)
          action ||= caller_method_name(caller)
          # logger.info ("testing template:" + "\#{self.class.controller_path}/\#{action}") if logger
          
          if template_exists?("\#{self.class.controller_path}/\#{action}")
            render :action => action
          else
            @scaffold_class = #{class_name}
            @scaffold_singular_name, @scaffold_plural_name = "#{singular_name}", "#{plural_name}"
            @scaffold_models_path = @template.method("#{models_path}")
            @scaffold_model_path = @template.method("#{model_path}")
            @scaffold_new_model_path = @template.method("#{new_model_path}")
            @scaffold_edit_model_path = @template.method("#{edit_model_path}")
            add_instance_variables_to_assigns
            @template.instance_variable_set("@content_for_layout", @template.render_file(scaffold_path(action), false))
            if !active_layout.nil?
              render :file => active_layout, :use_full_path => true
            else
              render :file => scaffold_path('layout')
            end
          end
        end
        def scaffold_path(template_name)
          File::join RAILS_ROOT, "vendor/plugins/dynamic_scaffold_resource/lib/templates/" + template_name + ".rhtml"
        end
        def caller_method_name(caller)
          caller.first.scan(/`(.*)'/).first.first # ' ruby-mode
        end
      end_eval
    end
  end
end